#include "ContractManager.h"
#include "LogManager.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFileInfo>
#include <QDir>
#include <fstream>

namespace Common {

ContractManager* ContractManager::instance() {
    static ContractManager instance;
    return &instance;
}

ContractManager::ContractManager(QObject* parent) 
    : QObject(parent) {
}

bool ContractManager::init(const QString& configFile) {
    if (m_initialized) {
        return true;
    }
    
    // 读取配置文件
    QFile file(configFile);
    if (!file.open(QIODevice::ReadOnly)) {
        MLOG_ERROR("contract", "Failed to open config file: {}", configFile.toStdString());
        return false;
    }
    
    QByteArray data = file.readAll();
    file.close();
    
    try {
        // 解析JSON
        auto json = nlohmann::json::parse(data.toStdString());
        
        // 检查是否是对象
        if (!json.is_object()) {
            MLOG_ERROR("contract", "Invalid config format: root element is not an object");
            return false;
        }
        
        // 遍历所有合约
        for (const auto& [code, contractJson] : json.items()) {
            try {
                // 使用已有的parseContractInfo函数解析合约信息
                Contract contract = parseContractInfo(contractJson);
                if (!contract.m_strCode.empty()) {
                    m_contracts[contract.m_strCode] = contract;
                    MLOG_DEBUG("contract", "Added contract: {} ({}) on {}", 
                              contract.m_strCode, contract.m_strName, contract.m_strExchg);
                }
            } catch (const std::exception& e) {
                MLOG_WARN("contract", "Failed to parse contract {}: {}", code, e.what());
                continue;  // 继续处理下一个合约
            }
        }
        
        m_initialized = true;
        MLOG_INFO("contract", "Successfully loaded {} contracts", m_contracts.size());
        
        // 强制刷新日志
        LOG_MANAGER->flush();
        
        return true;
    } catch (const std::exception& e) {
        MLOG_ERROR("contract", "Failed to parse config: {}", e.what());
        return false;
    }
}

Contract ContractManager::parseContractInfo(const nlohmann::json& json) {
    Contract info;
    
    try {
        MLOG_DEBUG("contract", "Starting to parse contract info");
        
        // 基本字符串信息
        info.m_strCode = json["code"].get<std::string>();
        info.m_strExchg = json["exchg"].get<std::string>();
        info.m_strName = json["name"].get<std::string>();
        info.m_strProduct = json["product"].get<std::string>();
        info.m_strSession = json["session"].get<std::string>();

        // 交易限制
        info.m_maxMktQty = json["maxmarketqty"].get<uint32_t>();
        info.m_maxLmtQty = json["maxlimitqty"].get<uint32_t>();
        info.m_minMktQty = json["minmarketqty"].get<uint32_t>();
        info.m_minLmtQty = json["minlimitqty"].get<uint32_t>();

        // 日期信息
        info.m_uOpenDate = std::stoul(json["opendate"].get<std::string>());
        info.m_uExpireDate = std::stoul(json["expiredate"].get<std::string>());

        // 保证金率
        info.m_dLongMarginRatio = json["longmarginratio"].get<double>();
        info.m_dShortMarginRatio = json["shortmarginratio"].get<double>();

        // 价格和数量信息
        info.m_priceTick = json["pricetick"].get<double>();
        info.m_iVolumeMultiple = json["volumemultiple"].get<int>();
        info.m_strikePrice = json["strikeprice"].get<double>();

        // 其他字段设置默认值
        info.m_uPrecision = 0;
        info.m_optType = OptionType::OT_None;
        info.m_strUnderlying = "";
        info.m_dUnderlyingScale = 0.0;

        MLOG_DEBUG("contract", "Successfully parsed contract: {}", info.m_strCode);
        return info;
    }
    catch (const std::exception& e) {
        MLOG_ERROR("contract", "Error parsing contract fields: {}", e.what());
        throw;
    }
}

Contract ContractManager::getContract(const std::string& code) const {
    auto it = m_contracts.find(code);
    if (it != m_contracts.end()) {
        return it->second;
    }
    return Contract();
}

bool ContractManager::hasContract(const std::string& code) const {
    return m_contracts.find(code) != m_contracts.end();
}

std::vector<Contract> ContractManager::getContractsByExchange(const std::string& exchg) const {
    std::vector<Contract> result;
    for (const auto& pair : m_contracts) {
        if (pair.second.m_strExchg == exchg) {
            result.push_back(pair.second);
        }
    }
    return result;
}

std::vector<Contract> ContractManager::getContractsByProduct(const std::string& product) const {
    std::vector<Contract> result;
    for (const auto& pair : m_contracts) {
        if (pair.second.m_strProduct == product) {
            result.push_back(pair.second);
        }
    }
    return result;
}

} // namespace Common 